package com.lancoo.edu.platform.operation.backupRestore.service.timer;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.lancoo.edu.platform.operation.backupRestore.constant.BackupRestoreConstant;
import com.lancoo.edu.platform.operation.backupRestore.constant.ScheduleTaskEnum;
import com.lancoo.edu.platform.operation.backupRestore.domain.po.BrSysTaskInfo;
import com.lancoo.edu.platform.operation.backupRestore.service.po.BrSysTaskInfoService;
import com.lancoo.edu.platform.operation.commons.task.TaskScheduler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.quartz.JobDetail;
import org.quartz.Trigger;

import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author lzh
 * @date 2024/6/20 16:51
 * @description 定时任务
 */
@Service
@Slf4j
@AllArgsConstructor
public class ScheduleTask {

    private final BrSysTaskInfoService brSysTaskInfoService;
    private final TaskScheduler taskScheduler;


    /**
     * 初始化定时任务
     */
    public void initTask() {
        // 1、获取全部定时任务
        List<BrSysTaskInfo> brSysTaskInfoList = brSysTaskInfoService.list();
        // 2、遍历，创建任务
        for (BrSysTaskInfo brSysTaskInfo : brSysTaskInfoList) {
            ScheduleTaskEnum scheduleTaskEnum = ScheduleTaskEnum.getEnumByTaskMethod(brSysTaskInfo.getTaskMethod());
            JobDetail jobDetail = taskScheduler.getJob(brSysTaskInfo.getTaskMethodName(), brSysTaskInfo.getTaskMethod(), scheduleTaskEnum.getClazz());
            Trigger trigger = buildTrigger(brSysTaskInfo);
            // 启动定时任务
            try {
                taskScheduler.startScheduler(jobDetail, trigger);
            } catch (Exception e) {
                log.error("【启动定时任务失败】", e);
            }
        }
    }

    /**
     * 构建触发器
     *
     * @param brSysTaskInfo 任务信息
     * @return 触发器
     */
    public Trigger buildTrigger(BrSysTaskInfo brSysTaskInfo) {
        // 2.1、获取cron触发器
        if (Objects.equals(brSysTaskInfo.getTaskType(), BackupRestoreConstant.TASK_TYPE_CRON)) {
            return taskScheduler.buildCronTrigger(brSysTaskInfo.getTaskId(), brSysTaskInfo.getTaskMethod(), DateUtil.date(), null, brSysTaskInfo.getTaskCorn());
        }
        // 2.2、获取interval触发器
        else if (Objects.equals(brSysTaskInfo.getTaskType(), BackupRestoreConstant.TASK_TYPE_INTERVAL)) {
            // 任务开始时间。凌晨3点
            DateTime startTime = DateUtil.offsetHour(DateUtil.beginOfDay(new Date()), 3);
            return taskScheduler.buildIntervalTrigger(brSysTaskInfo.getTaskId(), brSysTaskInfo.getTaskMethod(), startTime, null, brSysTaskInfo.getFrequency(), brSysTaskInfo.getFrequencyType());
        }
        return null;
    }

    /**
     * 更新触发器
     *
     * @param brSysTaskInfo 任务信息
     * @return 触发器
     */
    public boolean updateTrigger(BrSysTaskInfo brSysTaskInfo) {
        // 2.1、获取cron触发器
        if (Objects.equals(brSysTaskInfo.getTaskType(), BackupRestoreConstant.TASK_TYPE_CRON)) {
            return taskScheduler.updatedCronTrigger(brSysTaskInfo.getTaskId(), brSysTaskInfo.getTaskMethod(), DateUtil.date(), null, brSysTaskInfo.getTaskCorn());
        }
        // 2.2、获取interval触发器
        else if (Objects.equals(brSysTaskInfo.getTaskType(), BackupRestoreConstant.TASK_TYPE_INTERVAL)) {
            // 任务开始时间。凌晨3点
            DateTime startTime = DateUtil.offsetHour(DateUtil.beginOfDay(new Date()), 3);
            return taskScheduler.updatedIntervalTrigger(brSysTaskInfo.getTaskId(), brSysTaskInfo.getTaskMethod(), startTime, null, brSysTaskInfo.getFrequency(), brSysTaskInfo.getFrequencyType());
        }
        return false;
    }

    /**
     * 是否可以执行
     *
     * @param group  任务分组
     * @param taskId 任务Id
     * @return 是否可以执行
     */
    public boolean beExecute(String group, String taskId) {
        BrSysTaskInfo brSysTaskInfo = brSysTaskInfoService.getById(taskId);
        if (Objects.isNull(brSysTaskInfo)) {
            log.info("【任务-{}不存在】", taskId);
            return true;
        }
        if (Objects.equals(brSysTaskInfo.getBeTurn(), BackupRestoreConstant.TASK_TURN_OFF)) {
            log.info("【任务-{}已关闭】", brSysTaskInfo.getTaskMethod());
            return true;
        }
        return false;
    }
}
